import greenfoot.*;
import java.util.*;

/**
 * Esta clase representa el mundo JackWorld
 * desde la cual se crean todos los objetos
 * del juego.
 * 
 * @author Carlos Bretherton.
 * @version 01 de Mayo del 2012
 */
public class JackWorld extends World
{
    private static final int CUBOFIJO = 1;
    private static final int CUBOMOV = 2; 
    private static final int JACKFROST = 3;
    private static final int SNOWBOX = 4;
    private static final int SNOWBALL = 5;
    private static final int PINGUINO = 6;
    private Random r = new Random();
    protected int nivel;
    protected int Arr[][] = new int[15][15];
    protected int vidas;
    protected int puntos;
    protected int nenemigos;
    protected Time time;
    
    /**
     * Contructor del mundo JackWorld.
     * 
     */
    public JackWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(500, 540, 1, true);
        setPaintOrder(Mensajes.class,Pinguino.class,Cubo.class);
        setActOrder();
        menu();
    }
    
    /**
     * Inicializa la pantalla del Menu y define
     * los valores de las vidas, nivel, puntos
     * y número de enemigos.
     */
    public void menu()
    {
        setBackground("background.png");
        vidas = 3;
        nivel = 0;
        puntos = 0;
        nenemigos = 0;
        addObject(new Play(), 150, 345);//Agrega al mundo el boton de Jugar.
        addObject(new Credits(), 300, 425);//Agrega al mundo el boton de Creditos.
        addObject(new Help(), 413, 505);//Agrega al mundo el boton de Ayuda.
    }
    
    
    /**
     * Muestra en pantalla el nivel
     * que comenzara o si a completado
     * los 10 niveles muestra el mensaje
     * de ganador.
     */
    public void iniciarNivel()
    {
        nivel++;
        if(nivel < 11)
        {
            removeObjects(getObjects(Actor.class));
            setBackground("background2.png");
            addObject(new Nivel(nivel), getWidth()/2, getHeight()/2);
        }
        else
        {
            removeObjects(getObjects(Actor.class));
            addObject(new Win(), getWidth()/2, getHeight()/2);
        }
    }
    
    /**
     * Crea el mundo del juego de acuerdo
     * al nivel, y agrega los objetos vidas,
     * tiempo y puntos.
     */
    public void jugar()
    {
        time = new Time();
        addObject(time, 200, 25);
        addObject(new Lifes(),52, 25);
        addObject(new Points(),375, 25);
        creaNivel();
    }
    
        
    /**
     * En caso de perder reinicia el mundo
     * y regresa al menu.
     */  
    public void reiniciar()
    {
        removeObjects(getObjects(Actor.class));
        setBackground("background2.png");
        addObject(new Lose(), getWidth()/2, getHeight()/2 );
    }
      
    /**
     * Muestra en pantalla los creditos
     * del juego.
     */
    public void credits()
    {
        removeObjects(getObjects(Boton.class));
        setBackground("backgroundcredits.png");
        addObject(new Enter(), 0, 0);
    }
    
    /**
     * Muestra en pantalla la ayuda
     * del juego.
     */
    public void help()
    {
        removeObjects(getObjects(Boton.class));
        setBackground("backgroundhelp.png");
        addObject(new Enter(), 0, 0);
    }
    
    /**
     * Define aleatoriamente los niveles a traves 
     * de una matriz, y al final de acuerdo a esa
     * matriz agrega los objetos depende de que 
     * tipo tenga cada lugar de la matriz.
     */
    private void creaNivel()
    {
        defineCubos();
        defineEnemigos();
        agregaObjetos();        
    }
    
    /**
     * Define el mundo con cubos fijos 
     * y cubos movibles.
     */
    private void defineCubos()
    {
        for(int i = 0; i < 15; i++)
        {
            for(int j = 0; j < 15; j++)
            {
                 Arr[i][j] = 0;
            }
        }
        
        Arr[3][3] = PINGUINO;//Ubicación en el arreglo del Pinguino.
        
        for(int i = 0; i < 15; i++)
        {
            for(int j = 0; j < 15; j++)
            {
                if(i == 0 || i == 14 || j == 0 || j == 14)
                {
                    Arr[i][j] = CUBOFIJO;
                }
            }
        }
        
        for(int i = 0; i < 15; i++)
        {
            for(int j = 0; j < 15; j++)
            {
                if( Arr[i][j] == 0)
                {
                    Arr[i][j] = r.nextInt( 3 );
                }
            }
        }
    }
    
    /**
     * De acuerdo al número del nivel 
     * define el número de enemigos y
     * los posiciona en el mundo aleatoriamente.
     */
    private void defineEnemigos()
    {
        int NJF;//Número de JackFrost en el juego.
        int NSBX;//Número de SnowBox en el juego.
        int NSBll;//Número de SnowBall en el juego.
        
        switch(nivel)
        {
            case 1: NJF = 3;
                    NSBX = 0;
                    NSBll = 0;
            break;
            case 2: NJF = 4;
                    NSBX = 0;
                    NSBll = 0;
            break;
            case 3: NJF = 5;
                    NSBX = 0;
                    NSBll = 0;
            break;
            case 4: NJF = 3;
                    NSBX = 3;
                    NSBll = 0;
            break;
            case 5: NJF = 3;
                    NSBX = 4;
                    NSBll = 0;
            break;
            case 6: NJF = 3;
                    NSBX = 5;
                    NSBll = 0;
            break;
            case 7: NJF = 4;
                    NSBX = 3;
                    NSBll = 2;
            break;
            case 8: NJF = 4;
                    NSBX = 3;
                    NSBll = 3;
            break;
            case 9: NJF = 4;
                    NSBX = 3;
                    NSBll = 3;
            break;
            case 10: NJF = 4;
                     NSBX = 4;
                     NSBll = 4;
            break;
            default: NJF = 0;
                     NSBX = 0;
                     NSBll = 0;
        }
        
        int total = nenemigos = NJF + NSBX + NSBll;//Número total de enemigos.
        
        do{
            for(int i = 0; i < 15; i++)
            {
                for(int j = 0; j < 15; j++)
                {
                    switch( r.nextInt( 15 ) )
                    {
                        case JACKFROST: if( Arr[i][j] == 0 )
                                        {
                                            if( NJF > 0)
                                            {
                                                Arr[i][j] = JACKFROST;
                                                NJF--;
                                                total--;
                                            }
                                        }
                        break;
                        case SNOWBOX: if( Arr[i][j] == 0 )
                                      {
                                          if( NSBX > 0)
                                          {
                                              Arr[i][j] = SNOWBOX;
                                              NSBX--;
                                              total--;
                                          }
                                      }
                        break;
                        case SNOWBALL: if( Arr[i][j] == 0 )
                                       {
                                           if( NSBll > 0)
                                           {
                                               Arr[i][j] = SNOWBALL;
                                               NSBll--;
                                               total--;
                                           }
                                       }
                        break;
                    }
                }
            }
        }while( total > 0 );
    }
    
    /**
     * Agrega todos los personajes en el mundo,
     * como pinguino, enemigos, cubos.
     */
    private void agregaObjetos()
    {
        int x = 18;// Cordenada en x del personaje.
        int y = 60; //Cordenada en y del personaje.
        
        for(int i = 0; i < 15; i++)//renglones
        {
            for(int j = 0; j < 15; j++)//columnas
            {
                switch( Arr[i][j] )
                {
                    case CUBOFIJO: addObject(new Cubo( 1, j, i ), x + (33*j), y + (33*i) );
                    break;
                    case CUBOMOV: addObject(new Cubo( 2, j, i ), x + (33*j), y + (33*i) );
                    break;
                    case JACKFROST: addObject(new JackFrost( 3, j, i ), x + (33*j), y + (33*i) );
                                    Arr[i][j] = 0;
                    break;
                    case SNOWBOX: addObject(new SnowBox( 4, j, i ), x + (33*j), y + (33*i) );
                                  Arr[i][j] = 0;
                    break;
                    case SNOWBALL: addObject(new SnowBall( 5, j, i ), x + (33*j), y + (33*i) );
                                   Arr[i][j] = 0;
                    break;
                    case PINGUINO: addObject(new Pinguino( 6, j, i ), x + (33*j), y + (33*i) );
                                   Arr[i][j] = 0;
                    break;
                }
            }
        }
    }
}
